package xin.javashare.javacollectionsframework.mycollectionsframework;

//import java_collections_framework.my_collections_framework.MyAbstractList;

public class MyArrayList<E> extends MyAbstractList<E> {
    public static final int INITIAL_CAPACITY = 16;
    private E[] data = (E[]) new Object[INITIAL_CAPACITY];

    /**
     * Create a default list
     */
    public MyArrayList() {
    }

    public MyArrayList(E[] objects) {
        for (int i = 0; i < objects.length; i++) {
            add(objects[i]); // Warning: don't use super(objects)!--------?
        }
    }

    /**
     * Add a new element at the specified index in this list
     */
    public void add(int index, E e) {
        ensureCapacity();

        // Move the elements at the right after  the specified index
        for (int i = size - 1; i >= index; i--) {
            data[i + 1] = data[i];
        }

        // Insert new element to data[index]
        data[index] = e;

        // Increase size by 1
        size++;
    }

    /**
     * Create a new large array, double the current size + 1
     */
    private void ensureCapacity() {
        if (size >= data.length) {
            E[] newData = (E[]) (new Object[size * 2 + 1]);
            System.arraycopy(data, 0, newData, 0, size);
            data = newData;
        }
    }

    /**
     * Clear the list
     */
    public void clear() {
        data = (E[]) (new Object[INITIAL_CAPACITY]);
        size = 0;
    }

    /**
     * Return true if the list contains the elements
     */
    public boolean contains(E e) {
        for (int i = 0; i < size; i++)
            if (e.equals(data[i])) return true;

        return false;
    }

    public E get(int index) {
        return data[index];
    }

    public int indexOf(E e) {
        for (int i = 0; i < size; i++)
            if (e.equals(data[i])) return i;

        return -1;
    }


    public int lastIndexOf(E e) {
        for (int i = size - 1; i >= 0; i--)
            if (e.equals(data[i])) return i;

        return -1;
    }

    public E remove(int index) {
        E e = data[index];

        // Shift data to the left
        for (int j = index; j < size - 1; j++)
            data[j] = data[j + 1];

        data[size - 1] = null;

        // Decrement size
        size--;

        return e;
    }

    public E set(int index, E e) {
        E old = data[index];
        data[index] = e;

        return old;
    }

    /**
     * Override to toString() to return elements in the list
     */
    public String toString() {
        StringBuilder result = new StringBuilder("[");

        for (int i = 0; i < size; i++) {
            result.append(data[i]);
            if (i < size - 1) result.append(", ");
        }

        return result.toString() + "]";
    }

    /**
     * Trims the capacity to current size
     */
    public void trimToSize() {
        if (size != data.length) {
            // If size == capacity, no need to trim
            E[] newData = (E[]) (new Object[size]);
            System.arraycopy(data, 0, newData, 0, size);
            data = newData;
        }
    }
}
